package com.rr.mymoney.jsf;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

import com.rr.mymoney.bo.AccountBo;
import com.rr.mymoney.bo.CurrencyBo;
import com.rr.mymoney.model.Account;
import com.rr.mymoney.model.Currency;
import com.rr.mymoney.model.util.ModelFactory;
import com.rr.mymoney.security.SecurityUtils;

// Spring instantiates the object, so there is no use for JSF annotations
@Controller
@Scope("view")
public class AccountsController extends AbstractController {

    private static final long serialVersionUID = -5542950728737419163L;

    private static transient Logger log = Logger.getLogger(AccountsController.class);

    private transient AccountBo accountBo;
    private transient CurrencyBo currencyBo;

    private List<Account> accounts;
    private Account selectedAccount;
    private Account account = ModelFactory.newAccount();

    @Autowired
    public void setAccountBo(AccountBo accountBo) {
	this.accountBo = accountBo;
    }

    @Autowired
    public void setCurrencyBo(CurrencyBo currencyBo) {
	this.currencyBo = currencyBo;
    }

    public List<Account> getAccounts() {
	if (accounts == null) {
	    accounts = accountBo.getByUserId(getLoggedUser().getId());
	}
	return accounts;
    }

    public Account getSelectedAccount() {
	return selectedAccount;
    }

    public void setSelectedAccount(Account selectedAccount) {
	this.selectedAccount = selectedAccount;
	account = ModelFactory.newAccount();
    }

    public Account getAccount() {
	return account;
    }

    public void setAccount(Account account) {
	this.account = account;
    }

    public void saveAccount() {
	account.setUser(SecurityUtils.getLoggedUser());
	log.debug("save account: " + account.toString());
	accountBo.saveOrUpdate(account);
	accounts = null;
	getAccounts();
	account = ModelFactory.newAccount();
    }

    public void updateAccount() {
	log.debug("update account: " + selectedAccount.toString());
	accountBo.saveOrUpdate(selectedAccount);
	accounts = null;
	getAccounts();
    }

    public void deleteAccount() {
	try {
	    log.debug("delete account: " + selectedAccount.toString());
	    accountBo.delete(selectedAccount);
	    accounts = null;
	    getAccounts();
	} catch (Exception e) {
	    FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, "Delete", e.getMessage());
	    FacesContext.getCurrentInstance().addMessage(null, message);
	    log.error("Error on delete: ", e);
	}
    }

    public Map<String, String> getCurrencies() {
	Map<String, String> retVal = new HashMap<String, String>();
	for (Currency currency : currencyBo.getAll()) {
	    retVal.put(currency.getLabel(), currency.getId());
	}
	return retVal;
    }

}
